<?php
namespace app\api3\controller;

use think\Request;
use think\Db;
set_time_limit(0);
class TaskFile extends Base{
    public $request = null;
    protected $actionTime = 0;
    protected $task = null;
    protected $startTime = 0;
    protected $version = '';
    protected $lockFile = '';
    protected $simulation = [

    ];
    public function __construct(){
        $this->startTime = microtime(true);
        $this->actionTime = time();
        $this->request = Request::instance();
        $this->version = $this->request->param('v/s','');
        setGlobalsSysVersion($this->version);
    }
    public function index(){
        $this->task = Db::name('task_file')->where('isdelete=0')->field('id,flag,num,f_num,f_time,user_id,logical_data,create_time')->order('id')->find();
        if( !is_null($this->task) ) {
            if( $this->isDoIng() ) {
                echo '执行中';
            } else {
                $this->start();
                $this->end();
            }
        }
    }
    protected function isDoIng(){
        $fileName = \think\Config::get('task.lock_file').('' === $this->version ? '' : $this->version).'.txt';
        $dir = ROOT_PATH.'public'.getUploadFileDir('text');
        if (!is_dir($dir)){ mkdir($dir); }
        $this->lockFile = $dir.$fileName;
        if( is_file($this->lockFile) ) {
            $fp = fopen($this->lockFile,"r");
            $str = (int)fread($fp,1);
            fclose($fp);
            if( 0 === $str ) {
                //file_put_contents($this->lockFile,'1'); //设置未为未执行
                return true;
            } else {
                file_put_contents($this->lockFile,'0');
                return false;

            }
        } else {
            file_put_contents($this->lockFile,'0');
            return false;
        }
    }
    protected function end(){
        file_put_contents($this->lockFile,'1');
    }
    protected function start(){
        if( $this->task['num'] <= $this->task['f_num'] ) {
            $this->del();
            return true;
        }
        switch ( (int)$this->task['flag'] ) {
            case 1:
                $this->down_deskmate_code();
                break;
            case 2:
                $this->reset_deskmate_code();
                break;
            default:
                $this->del();
        }
        sleep(1);
        return true;
    }
    /*
     * $reason 逻辑删除原因 */
    protected function del( $reason = '' ){
        '' === $reason ? Db::name('task_file')->where("id=".$this->task['id'])->delete() : Db::name('task_file')->where("id=".$this->task['id'])->update(['isdelete'=>1,'reason'=>$reason]);
    }
    //下载同桌二维码
    protected function down_deskmate_code(){
        $deskmate = Db::name('deskmate')->where('uid='.$this->task['user_id'])->field('id,shop_img,shop_img_round,code_num')->find();
        if( !$deskmate || $deskmate['code_num'] >= 99 ) {
            $this->del();
            return;
        }
        $hasNum = $this->task['num'] - $this->task['f_num'];
        $maxNum = 20 < $hasNum ? 20 : $hasNum;
        for( $i=0;$i<$maxNum;$i++ ) {
            $index = $deskmate['code_num']+1+$i;
            if( $index > 99 ) {
                $this->del();
                return;
            }
            $showTitle = (10 > $index ? '0'.$index : $index).'号';
            $code = $this->getQrCode('pages/deskmate/show','deskmate_'.$deskmate['id'].'_'.$index);
            if( '' === $code ) {
                $this->del('下载二维码失败');
                return;
            }
            usleep(500000);
            //sleep(10);
            $showFilename = substr($code,0,-4).'_0.jpg';
            vendor('Draw.GdImage');
            $is = \GdImage::deskmateCode(
                ROOT_PATH .'public'.$showFilename,
                ROOT_PATH .'public/images/deskmate.jpg',
                getImgHost().$code,
                getImgHost().$deskmate['shop_img_round'],
                $showTitle);
            if( !$is ) {
                $this->del('图片合成失败');
                return;
            }
            $insertData = [
                'shop_id'=>$deskmate['id'],
                'uid'=>$this->task['user_id'],
                'url'=>$code,
                'show_url'=>$showFilename,
                'index'=>$index,
                'img_time'=>$this->actionTime,
                'status'=>1,
                'scan_num'=>100,
                'msg_num'=>100
            ];
            Db::startTrans();
            try{
                $code_id = Db::name('deskmate_code')->insertGetId($insertData);
                Db::name('deskmate')->where('uid='.$this->task['user_id'])->setInc('code_num',1);
                $simulation = $this->simulation;
                shuffle($simulation);
                $scan = [];
                $msg = [];
                foreach ( $simulation as $k=>$v) {
                    $scan[] = [
                        'code_id'=>$code_id,
                        'shop_id'=>$deskmate['id'],
                        'scan_uid'=>$v['scan_uid'],
                        'scan_name'=>$v['scan_name'],
                        'scan_img'=>getImgHost().$v['scan_img'],
                        'sex'=>$v['sex'],
                        'weixin'=>$v['weixin'],
                        'create_time'=>$this->actionTime + ($k*20)
                    ];
                    $msg[] = [
                        'shop_id'=>$deskmate['id'],
                        'scan_id'=>0,
                        'scan_uid'=>$v['scan_uid'],
                        'weixin'=>$v['weixin'],
                        'message'=>$v['msg'],
                        'create_time'=>$this->actionTime + ($k*20)
                    ];
                }
                Db::name('deskmate_scan')->insertAll($scan);
                $last_id = Db::name('deskmate_scan')->getLastInsID();
                foreach ( $msg as $k=>$v ) {
                    $msg[$k]['scan_id'] = $last_id + $k;
                }
                Db::name('deskmate_msg')->insertAll($msg);
                if( $i === $hasNum - 1 ) {
                    Db::name('task_file')->where("id=".$this->task['id'])->delete();
                } else {
                    Db::name('task_file')->where('id='.$this->task['id'])->inc('f_num',1)->update([
                        'f_time'=>(int)((microtime(true)-$this->startTime)*1000)+5000
                    ]);
                }
                // 提交事务
                Db::commit();
                $this->startTime = microtime(true);
            } catch (\Exception $e) {
                // 回滚事务
                Db::rollback();
                $this->del('保存数据失败');
                return;
            }
        }
        return true;
    }
    //重置已经生成过的二维码
    protected function reset_deskmate_code(){
        $deskmate = Db::name('deskmate')->where('uid='.$this->task['user_id'])->field('id,shop_img,shop_img_round,code_num,img_time')->find();
        if( !$deskmate || '' === $deskmate['shop_img_round'] ) {
            $this->del();
            return;
        }
        $list = Db::name('deskmate_code')->where('status=1 AND uid='.$this->task['id'].' AND img_time<'.$deskmate['img_time'])
            ->order('index')->field('id,url,show_url,scan_num,msg_num')->select();
        if( !$list ) {
            $this->del();
            return;
        }
        $flg = date('md');
        $hasNum = count($list,0);
        vendor('Draw.GdImage');
        foreach ( $list as $k=>$v ){
            if( 20 < $k ) {
                break;
            }
            $newPath = substr($v['url'],0,-4).'_'.$flg.'.jpg';
            $is = \GdImage::resetDeskmateCode(ROOT_PATH .'public'.$newPath,getImgHost().$v['show_url'],getImgHost().$deskmate['shop_img_round']);
            if( !$is ) {
                $this->del('图片合成失败');
                return;
            }
            Db::startTrans();
            try{
                Db::name('deskmate_code')->where('id='.$v['id'])->update([
                    'show_url'=>$newPath,
                    'img_time'=>time()
                ]);
                if( $k === $hasNum - 1 ) {
                    Db::name('task_file')->where("id=".$this->task['id'])->delete();
                } else {
                    Db::name('task_file')->where('id='.$this->task['id'])->inc('f_num',1)->update([
                        'f_time'=>(int)((microtime(true)-$this->startTime)*1000)+500
                    ]);
                }
                // 提交事务
                Db::commit();
                $this->startTime = microtime(true);
                usleep(500000);
            } catch (\Exception $e) {
                // 回滚事务
                Db::rollback();
                $this->del('保存数据失败');
                return;
            }
        }
        return;
    }

}

